package com.lyncs.ods.utils;

import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
import com.lyncs.ods.common.api.CommonPage;
import com.lyncs.ods.constant.LyncsOdsConstant;
import com.lyncs.ods.modules.goods.model.SpuInfo;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.ObjectUtils;

import java.util.Comparator;
import java.util.List;
import java.util.Objects;
import java.util.function.BiFunction;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @author alex
 * @date 2022/4/27 01:58
 * @description
 */
public class PageUtil {

    public static <R> CommonPage<R> empty(Integer page, Integer pageSize) {
        return new CommonPage<R>().setPage(page).setPageSize(pageSize).setTotal(0L);
    }

    public static <T, R> CommonPage<R> count(LambdaQueryChainWrapper<T> conditionWrapper, Integer page, Integer pageSize) {
        return new CommonPage<R>().setPage(page).setPageSize(pageSize).setTotal(Long.valueOf(conditionWrapper.count()));
    }

    public static String getSortSql(String sortFiledName, Long sortFiledVal) {
        if (Objects.isNull(sortFiledName) || sortFiledVal == null) {
            return "";
        }
        //String valStr = sortFiledVal.stream().map(String::valueOf).collect(Collectors.joining(LyncsOdsConstant.Common.COMMA));
        return "ORDER BY FIELD(" + sortFiledName + "," + sortFiledVal + ") DESC";
    }

    public static String getLastSql(Integer page, Integer pageSize) {
        Long val = null;
        return getLastSql(page, pageSize, null, val);
    }

    public static String getLastSql(Integer page, Integer pageSize, String sortFiledName, List<Long> sortFiledVal) {
        if (Objects.isNull(page) || Objects.isNull(pageSize)) {
            return "";
        }
        String limitSql = " limit " + getOffset(page, pageSize) + ", " + pageSize;
        if (Objects.isNull(sortFiledName) || CollectionUtils.isEmpty(sortFiledVal)) {
            return "ORDER BY create_time DESC" + limitSql;
        }
        String valStr = sortFiledVal.stream().map(String::valueOf).collect(Collectors.joining(LyncsOdsConstant.Common.COMMA));
        return "ORDER BY FIELD(" + sortFiledName + "," + valStr + ") DESC, create_time DESC" + limitSql;
    }

    public static String getPageSqlOnly(Integer page, Integer pageSize) {
        if (Objects.isNull(page) || Objects.isNull(pageSize)) {
            return "";
        }
        return " limit " + getOffset(page, pageSize) + ", " + pageSize;
    }


    public static String sortByUpdateTime(Integer page, Integer pageSize, String sortFiledName, List<Long> sortFiledVal) {
        if (Objects.isNull(page) || Objects.isNull(pageSize)) {
            return "";
        }
        String limitSql = " limit " + getOffset(page, pageSize) + ", " + pageSize;
        if (Objects.isNull(sortFiledName) || CollectionUtils.isEmpty(sortFiledVal)) {
            return "ORDER BY update_time DESC" + limitSql;
        }
        String valStr = sortFiledVal.stream().map(String::valueOf).collect(Collectors.joining(LyncsOdsConstant.Common.COMMA));
        return "ORDER BY FIELD(" + sortFiledName + "," + valStr + ") DESC, update_time DESC" + limitSql;
    }

    public static String getLastSql(Integer page, Integer pageSize, String sortFiledName, Long sortFiledVal) {
        if (Objects.isNull(page) || Objects.isNull(pageSize)) {
            return "";
        }
        String limitSql = " limit " + getOffset(page, pageSize) + ", " + pageSize;
        if (Objects.isNull(sortFiledName) || Objects.isNull(sortFiledVal)) {
            return "ORDER BY create_time DESC" + limitSql;
        }
        return "ORDER BY FIELD(" + sortFiledName + "," + sortFiledVal + ") DESC, create_time DESC" + limitSql;
    }

    public static <T, R> CommonPage<R> result(List<T> data, Function<T, R> covertFunc, CommonPage<R> commonPage, Function<R, Long> sortedFunc) {
        if (CollectionUtils.isEmpty(data) || commonPage == null) {
            return commonPage;
        }
        return commonPage.setList(data.stream().map(covertFunc).filter(Objects::nonNull).sorted(Comparator.comparing(sortedFunc, Comparator.reverseOrder())).collect(Collectors.toList()));
    }

    public static <T, R> CommonPage<R> result(List<T> data, Function<T, R> covertFunc, CommonPage<R> commonPage) {
        if (CollectionUtils.isEmpty(data) || commonPage == null) {
            return commonPage;
        }
        return commonPage.setList(data.stream().map(covertFunc).filter(Objects::nonNull).collect(Collectors.toList()));
    }

    public static <T, U, R> CommonPage<R> result(List<T> data, U u, BiFunction<T, U, R> covertFunc, CommonPage<R> commonPage) {
        if (CollectionUtils.isEmpty(data) || commonPage == null) {
            return commonPage;
        }
        return commonPage.setList(data.stream().map(t -> covertFunc.apply(t, u)).filter(Objects::nonNull).collect(Collectors.toList()));
    }

    public static Integer getOffset(Integer page, Integer pageSize) {
        return (page - 1) * pageSize;
    }
}
